#ifndef COLLISION_H
#define COLLISION_H

#include "includes.h"
#include "rendermanager.h"
#include "RigidBody.h"

#define COLLIDE_EPSILON 0.0
#define COLLIDE_BODY_EPSILON 0.05

class Collision
{
public:    
    static bool hasCollided(RigidBody& b);
    static bool hasCollided(RigidBody &b, vector3<float>& normal);
    static bool hasCollidedLeft(RigidBody &b);
    static bool hasCollidedRight(RigidBody &b);
    static bool hasCollidedUp(RigidBody &b);
    static bool hasCollidedDown(RigidBody &b);
    static bool hasCollidedFront(RigidBody &b);
    static bool hasCollidedBack(RigidBody &b);

    static bool hasCollidedWithBody(RigidBody& a, RigidBody& b){
        return a.geometry.hasContactedAABB(b.geometry);
    }

    static bool hasCollidedWithBodyAtOffset(RigidBody& a, RigidBody& b, float offset){
        AABB temp = a.geometry;
        temp.add(vector3<float>(offset,offset,offset));
        return temp.hasContactedAABB(b.geometry);
    }

    static bool hasCollidedAtOffset(RigidBody& b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollided(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool hasCollidedLeftAtOffset(RigidBody &b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollidedLeft(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool hasCollidedRightAtOffset(RigidBody &b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollidedRight(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool hasCollidedUpAtOffset(RigidBody &b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollidedUp(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool hasCollidedDownAtOffset(RigidBody &b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollidedDown(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool hasCollidedFrontAtOffset(RigidBody &b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollidedFront(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool hasCollidedBackAtOffset(RigidBody &b,vector3<float> offset){
        b.geometry.translate(offset);
        bool ret=hasCollidedBack(b);
        b.geometry.translate(-offset);
        return ret;
    }

    static bool checkForVoxelCollision(RigidBody& b, vector3<float>& v){
        return REND->isVoxelDrawn((int)v.x,(int)v.y,(int)v.z) && b.geometry.hasContactedVoxel(v);
    }
};

#endif // COLLISION_H
